package cn.wapache.i18n;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 
 * 错误码统一采用16进制表示, 总长度为10个字节
 * 成功约定为0x00000000
 * 
 * 建议错误码为以下方式:
 * 0           1234                56     789
 * org.wapache.app/project.version.module.errors
 * 第一位,为公司的域名,最多可支持16个域名
 * 
 * 其他编码尽量避免使用这种类型的命名方式, 建议使用有明确意义的方式命名,如
 * domainName.appName.moduleName.messageName
 * 
 * @author ykuang
 *
 */
public class I18n {

	public static String SUCCESS = "0x00000000";
	public static String FAILED  = "0xAAAAAAAA";
	public static String ERROR   = "0xEEEEEEEE";
	public static String UNKNOWN = "0xFFFFFFFF";

	/** 为了提高性能,不用每次都去遍历services,一般的应用应该只有一个service就够了 */
	protected static I18nService defaultService;
	
	protected static List<I18nService> services;
	
	public static <T extends I18nService> T register(T service) {
		
		if(defaultService==null){
			defaultService = service;
		}else if(defaultService==service){
			// do nothing
		}else if(services==null){
			services = new ArrayList<>();
			if( ! services.contains(service)){
				services.add(service);
			}
		}
		
		return service;
	}
	
	public static void unregister(I18nService service) {

		if(services!=null && services.remove(service)){
			return;
		}
		
		if(defaultService==service){
			defaultService = null;
			if( ! services.isEmpty()){
				defaultService = services.remove(0);
			}
		}
		
	}
	
	public static I18nEntry get(String key){

		I18nEntry entry = null;
		
		if(defaultService==null){
			throw new IllegalStateException("there is no i18n service registered!");
			//defaultService = newService("default"," the default i18n service.");
		}
		
		entry = defaultService.get(key);
		
		if(entry==null && services!=null){
			for (I18nService s : services) {
				entry = s.get(key);
				if(entry!=null){ break;}
			}
		}
		
		return entry;
	}
	
	public static Optional<I18nEntry> getOptional(String key){
		return Optional.ofNullable(get(key));
	}
	
	public static I18nEntry getOrDefault(String key, I18nEntry def){
		I18nEntry entry = get(key);
		return entry==null ? def : entry;
	}
	
	public static String getDescription(String key,  Object... values){
		I18nEntry entry = get(key);
		return entry != null ? entry.getDescription(values) : key;
	}

	public static String getDescription(String def, String key, Object... values){
		I18nEntry entry = get(key);
		return entry != null ? entry.getDescription(values) : def;
	}
	
	public static DefaultI18nService newService(String name, String description){
		return new DefaultI18nService().setName(name).setDescription(description);
	}
	
	public static DefaultI18nService registerService(String name, String description){
		return register(newService(name,description));
	}
	
	public static I18nEntry newEntry(String key, String description){
		return new DefaultI18nEntry().setKey(key).setDescription(description);
	}
	
}
